package com.bsg.upm.service;

import java.text.MessageFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.http.HttpStatus;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bsg.upm.cache.DefinitionMetricClassCache;
import com.bsg.upm.constant.MonitorCommonMap;
import com.bsg.upm.constant.SysConstants;
import com.bsg.upm.dao.DefinitionMetricClassDao;
import com.bsg.upm.entity.DefinitionMetricClassEntity;
import com.bsg.upm.entity.DefinitionMetricEntity;
import com.bsg.upm.entity.SubServEntity;
import com.bsg.upm.entity.UnitEntity;
import com.bsg.upm.exception.APIException;
import com.bsg.upm.http.RespJson;
import com.bsg.upm.http.RespJsonFactory;

@Service
public class MonitorContainerConfigService extends BaseService {

	@Resource
	private DefinitionMetricClassCache definitionMetricClassCache;
	@Resource
	private DefinitionMetricClassDao definitionMetricClassDao;

	@Resource
	private MonitorHostConfigService monitorHostConfigService;

	public String getMetricType(String subservId, String metric) {

		if (definitionMetricCache.isExist(MonitorCommonMap.CONTAINER_TYPE, metric)) {
			return MonitorCommonMap.CONTAINER_TYPE;
		}

		SubServEntity subServEntity = subServDao.get(subservId);
		if (subServEntity == null) {
			return null;
		}

		return subServEntity.getSubOrder().getDefinitionSubServ().getName();
	}

	public JSONArray listContainersMetricClass(String subservId) throws APIException {
		JSONArray retJsonArray = new JSONArray();

		SubServEntity subServEntity = subServDao.get(subservId);
		if (subServEntity == null) {
			return retJsonArray;
		}

		String siteId = subServEntity.getServ().getOrder().getArea().getSite().getId();
		JSONArray containers = getContainersBySubServId(subservId);
		if (containers.isEmpty()) {
			return retJsonArray;
		}

		JSONArray metricConfigs = getContainersMetricClassFromHS(siteId, (String) containers.get(0));
		List<DefinitionMetricClassEntity> dfMetrics = definitionMetricClassCache.listDfMetricClassFromCache();

		for (Object config : metricConfigs) {
			retJsonArray.add(monitorHostConfigService.getMetricClassShowObject(dfMetrics, (JSONObject) config));
		}

		return retJsonArray;
	}

	public JSONArray listContainersEvent(String subservId) throws APIException {
		JSONArray retJsonArray = new JSONArray();

		SubServEntity subServEntity = subServDao.get(subservId);
		if (subServEntity == null) {
			return retJsonArray;
		}

		String siteId = subServEntity.getServ().getOrder().getArea().getSite().getId();
		JSONArray containers = getContainersBySubServId(subservId);
		if (containers.isEmpty()) {
			return retJsonArray;
		}

		JSONArray eventConfigs = getContainersEventFromHS(siteId, (String) containers.get(0));
		List<DefinitionMetricEntity> dfMetrics = definitionMetricCache.listDfMetricFromCache();
		for (Object config : eventConfigs) {
			retJsonArray.add(monitorHostConfigService.getEventShowObj(dfMetrics, (JSONObject) config));
		}

		return retJsonArray;
	}

	public RespJson enableMetricClassBySubServ(String subservId, String metricClass) throws APIException {
		SubServEntity subServEntity = subServDao.get(subservId);
		if (subServEntity == null) {
			return RespJsonFactory.build(HttpStatus.SC_GONE, "该子服务不存在");
		}
		String siteId = subServEntity.getServ().getOrder().getArea().getSite().getId();
		JSONArray containers = getContainersBySubServId(subservId);

		JSONObject paramJson = new JSONObject();
		paramJson.put("name", containers);

		String urlPattern = "/{0}/containers/{1}/enable";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION, metricClass);

		RespJson httpRespJson = sendHttpPut(siteId, SysConstants.INTERFACE_TYPE_HS, url, paramJson.toJSONString());
		if (!isHttp2XX(httpRespJson.getStatus())) {
			logger.error("MonitorContainerConfigService:enableMetricClassBySubServ fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}

		return RespJsonFactory.buildOK();
	}

	public RespJson disableMetricClassBySubServ(String subservId, String metricClass) throws APIException {
		SubServEntity subServEntity = subServDao.get(subservId);
		if (subServEntity == null) {
			return RespJsonFactory.build(HttpStatus.SC_GONE, "该子服务不存在");
		}
		String siteId = subServEntity.getServ().getOrder().getArea().getSite().getId();
		JSONArray containers = getContainersBySubServId(subservId);

		JSONObject paramJson = new JSONObject();
		paramJson.put("name", containers);

		String urlPattern = "/{0}/containers/{1}/disable";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION, metricClass);

		RespJson httpRespJson = sendHttpPut(siteId, SysConstants.INTERFACE_TYPE_HS, url, paramJson.toJSONString());
		if (!isHttp2XX(httpRespJson.getStatus())) {
			logger.error("MonitorContainerConfigService:disMetricClassBySubServ fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}

		return RespJsonFactory.buildOK();
	}

	public RespJson enableEventBySubServ(String subservId, String metric) throws APIException {
		SubServEntity subServEntity = subServDao.get(subservId);
		if (subServEntity == null) {
			return RespJsonFactory.build(HttpStatus.SC_GONE, "该子服务不存在");
		}
		String siteId = subServEntity.getServ().getOrder().getArea().getSite().getId();
		JSONArray containers = getContainersBySubServId(subservId);

		String relateMetric = definitionMetricCache.getMetric(MonitorCommonMap.CONTAINER_TYPE, metric);
		if (relateMetric == null) {
			throw new APIException(metric + ":don't find the metric");
		}

		JSONObject paramJson = new JSONObject();
		paramJson.put("name", containers);

		String urlPattern = "/{0}/containers/event/{1}/enable";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION, relateMetric);

		RespJson httpRespJson = sendHttpPut(siteId, SysConstants.INTERFACE_TYPE_HS, url, paramJson.toJSONString());
		if (!isHttp2XX(httpRespJson.getStatus())) {
			logger.error("MonitorContainerConfigService:enablecEventBySubServ fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}

		return RespJsonFactory.buildOK();
	}

	public RespJson disableEventBySubServ(String subservId, String metric) throws APIException {
		SubServEntity subServEntity = subServDao.get(subservId);
		if (subServEntity == null) {
			return RespJsonFactory.build(HttpStatus.SC_GONE, "该子服务不存在");
		}
		String siteId = subServEntity.getServ().getOrder().getArea().getSite().getId();
		JSONArray containers = getContainersBySubServId(subservId);

		String relateMetric = definitionMetricCache.getMetric(MonitorCommonMap.CONTAINER_TYPE, metric);
		if (relateMetric == null) {
			throw new APIException(metric + ":don't find the metric");
		}

		JSONObject paramJson = new JSONObject();
		paramJson.put("name", containers);

		String urlPattern = "/{0}/containers/event/{1}/disable";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION, relateMetric);

		RespJson httpRespJson = sendHttpPut(siteId, SysConstants.INTERFACE_TYPE_HS, url, paramJson.toJSONString());
		if (!isHttp2XX(httpRespJson.getStatus())) {
			logger.error("MonitorContainerConfigService:disableEventBySubServ fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}

		return RespJsonFactory.buildOK();
	}

	public RespJson updateEventLevelBySubServ(String subservId, String metric, String level, String start, String end)
			throws APIException {

		SubServEntity subServEntity = subServDao.get(subservId);
		if (subServEntity == null) {
			return RespJsonFactory.build(HttpStatus.SC_GONE, "该子服务不存在");
		}
		String siteId = subServEntity.getServ().getOrder().getArea().getSite().getId();
		JSONArray containers = getContainersBySubServId(subservId);

		String relateMetric = definitionMetricCache.getMetric(MonitorCommonMap.CONTAINER_TYPE, metric);
		if (relateMetric == null) {
			throw new APIException(metric + ":don't find the metric");
		}

		JSONObject paramJson = new JSONObject();
		paramJson.put("name", containers);
		paramJson.put("level", level);
		paramJson.put("start", start);
		paramJson.put("end", end);

		String urlPattern = "/{0}/containers/level/{1}";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION, relateMetric);

		RespJson httpRespJson = sendHttpPut(siteId, SysConstants.INTERFACE_TYPE_HS, url, paramJson.toJSONString());
		if (!isHttp2XX(httpRespJson.getStatus())) {
			logger.error("MonitorContainerConfigService:updateEventLevelBySubServ fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}

		return RespJsonFactory.buildOK();
	}

	public RespJson disableEventLevelBySubServ(String subservId, String metric, String level) throws APIException {
		SubServEntity subServEntity = subServDao.get(subservId);
		if (subServEntity == null) {
			return RespJsonFactory.build(HttpStatus.SC_GONE, "该子服务不存在");
		}
		String siteId = subServEntity.getServ().getOrder().getArea().getSite().getId();
		JSONArray containers = getContainersBySubServId(subservId);

		String relateMetric = definitionMetricCache.getMetric(MonitorCommonMap.CONTAINER_TYPE, metric);
		if (relateMetric == null) {
			throw new APIException(metric + ":don't find the metric");
		}

		JSONObject paramJson = new JSONObject();
		paramJson.put("name", containers);
		paramJson.put("level", level);

		String urlPattern = "/{0}/containers/level/{1}/disable";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION, relateMetric);

		RespJson httpRespJson = sendHttpPut(siteId, SysConstants.INTERFACE_TYPE_HS, url, paramJson.toJSONString());
		if (!isHttp2XX(httpRespJson.getStatus())) {
			logger.error("MonitorContainerConfigService:disableEventLevelBySubServ fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}

		return RespJsonFactory.buildOK();
	}

	public RespJson enableEventLevelBySubServ(String subservId, String metric, String level) throws APIException {
		SubServEntity subServEntity = subServDao.get(subservId);
		if (subServEntity == null) {
			return RespJsonFactory.build(HttpStatus.SC_GONE, "该子服务不存在");
		}
		String siteId = subServEntity.getServ().getOrder().getArea().getSite().getId();
		JSONArray containers = getContainersBySubServId(subservId);

		String relateMetric = definitionMetricCache.getMetric(MonitorCommonMap.CONTAINER_TYPE, metric);
		if (relateMetric == null) {
			throw new APIException(metric + ":don't find the metric");
		}

		JSONObject paramJson = new JSONObject();
		paramJson.put("name", containers);
		paramJson.put("level", level);

		String urlPattern = "/{0}/containers/level/{1}/enable";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION, relateMetric);

		RespJson httpRespJson = sendHttpPut(siteId, SysConstants.INTERFACE_TYPE_HS, url, paramJson.toJSONString());
		if (!isHttp2XX(httpRespJson.getStatus())) {
			logger.error("MonitorContainerConfigService:eableEventLevelBySubServ  fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}

		return RespJsonFactory.buildOK();
	}

	public String getMetricClassType(String metricClass) {
		DefinitionMetricClassEntity definitionMetricClassEntity = definitionMetricClassDao.get(metricClass);
		if (definitionMetricClassEntity == null) {
			return null;
		}

		return definitionMetricClassEntity.getType();

	}

	private JSONArray getContainersBySubServId(String id) {
		JSONArray ret = new JSONArray();

		Map<String, Object> paramMap = new HashMap<>();
		paramMap.put("subServId", id);
		List<UnitEntity> unitEntities = unitDao.list(paramMap);
		for (UnitEntity unitEntity : unitEntities) {
			ret.add(unitEntity.getRelateName());
		}

		return ret;
	}

	private JSONArray getContainersMetricClassFromHS(String siteId, String containerName) throws APIException {

		String urlPattern = "/{0}/metricclass/{1}?metric_object_type=container";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION, containerName);

		RespJson httpRespJson = sendHttpGet(siteId, SysConstants.INTERFACE_TYPE_HS, url);

		if (!isHttp2XX(httpRespJson.getStatus())) {
			logger.error("getContainersMetricClassFromHS fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}

		JSONObject datas = (JSONObject) httpRespJson.getData();
		if (datas.isEmpty()) {
			return new JSONArray();
		}

		return datas.getJSONArray("metric_configs");

	}

	private JSONArray getContainersEventFromHS(String siteId, String containerName) throws APIException {

		String urlPattern = "/{0}/event/{1}?metric_object_type=container";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION, containerName);

		RespJson httpRespJson = sendHttpGet(siteId, SysConstants.INTERFACE_TYPE_HS, url);

		if (!isHttp2XX(httpRespJson.getStatus())) {
			logger.error("getContainersEventFromHS fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}

		JSONObject datas = (JSONObject) httpRespJson.getData();
		if (datas.isEmpty()) {
			return new JSONArray();
		}

		return datas.getJSONArray("event_configs");

	}

	private boolean isHttp2XX(int status) {
		if (status == HttpStatus.SC_OK || status == HttpStatus.SC_CREATED) {
			return true;
		}
		return false;
	}

}